﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wizard.WizardControl.Models;
using System.Collections.ObjectModel;
using CoffeeLibrary;
using System.ComponentModel;
using Wizard.WizardControl;
using Wizard.CoffeeView;

namespace Wizard.CoffeeModel
{

    public class ExtrasStepViewModel : WizardStepViewModelBase<CupOfCoffee>
    {

        RegularOptionGroupViewModel<Flavorings> _availableFlavorings;
        RegularOptionGroupViewModel<Temperature> _availableTemperatures;

        public ExtrasStepViewModel( CupOfCoffee cupOfCoffee )
            : base( cupOfCoffee )
        {
        }

        /// <summary>
        /// Returns a read-only collection of all flavorings that the user can select.
        /// </summary>
        public RegularOptionGroupViewModel<Flavorings> AvailableFlavorings
        {
            get
            {
                if ( _availableFlavorings == null )
                {
                    this.CreateAvailableFlavorings();
                }
                return _availableFlavorings;
            }
        }

        /// <summary>
        /// Returns a read-only collection of all coffee temperatures that the user can select.
        /// </summary>
        public RegularOptionGroupViewModel<Temperature> AvailableTemperatures
        {
            get
            {
                if ( _availableTemperatures == null )
                {
                    this.CreateAvailableTemperatures();
                }
                return _availableTemperatures;
            }
        }

        void CreateAvailableFlavorings()
        {
            List<OptionViewModel<Flavorings>> list = new List<OptionViewModel<Flavorings>>();
            list.Add( new OptionViewModel<Flavorings>( Flavorings.JumpToPriorStep, 2, "Select this option to jump to previous step" ) );
            list.Add( new OptionViewModel<Flavorings>( Flavorings.Gingerbread, 3, "Gingery" ) );
            list.Add( new OptionViewModel<Flavorings>( Flavorings.Hazelnut, 4, "Nutty" ) );
            list.Add( new OptionViewModel<Flavorings>( Flavorings.IrishCream, 5, "Irish (and creamy)" ) );
            list.Add( new OptionViewModel<Flavorings>( Flavorings.Pumpkin, 1, "Note that this sorts to top" ) );
            list.Add( new OptionViewModel<Flavorings>( Flavorings.Vanilla, 6, "As in plain" ) );

            foreach ( OptionViewModel<Flavorings> option in list )
            {
                option.PropertyChanged += this.OnFlavoringOptionPropertyChanged;
            }

            list.Sort();

            _availableFlavorings = new RegularOptionGroupViewModel<Flavorings> { OptionModels = new ReadOnlyCollection<OptionViewModel<Flavorings>>( list ) };
        }

        void OnFlavoringOptionPropertyChanged( object sender, PropertyChangedEventArgs e )
        {
            // Since the user can select more than one additional flavoring to add to their
            // cup of coffee, we check all available flavorings and combine the enum values.

            Flavorings flavorings = Flavorings.None;

            foreach ( var option in AvailableFlavorings.OptionModels )
            {
                if ( option.IsSelected )
                {
                    flavorings |= option.GetValue();
                }
            }

            base.BusinessObject.Flavorings = flavorings;
        }

        void CreateAvailableTemperatures()
        {
            List<OptionViewModel<Temperature>> list = new List<OptionViewModel<Temperature>>();
            list.Add( new OptionViewModel<Temperature>( Temperature.ExtraHot, 1, "Some like it hot" ) );
            list.Add( new OptionViewModel<Temperature>( Temperature.Normal, 0, "So... normal" ) );
            list.Add( new OptionViewModel<Temperature>( Temperature.WithIce, 2, "Like that Vietnamese coffee" ) );

            foreach ( OptionViewModel<Temperature> option in list )
            {
                // Select the default value.
                if ( option.GetValue() == base.BusinessObject.Temperature )
                {
                    option.IsSelected = true;
                }
                option.PropertyChanged += this.OnTemperatureOptionPropertyChanged;
            }

            list.Sort();

            _availableTemperatures = new RegularOptionGroupViewModel<Temperature> { OptionModels = new ReadOnlyCollection<OptionViewModel<Temperature>>( list ) };
        }

        void OnTemperatureOptionPropertyChanged( object sender, PropertyChangedEventArgs e )
        {
            OptionViewModel<Temperature> option = sender as OptionViewModel<Temperature>;
            if ( option.IsSelected )
            {
                base.BusinessObject.Temperature = option.GetValue();
            }
        }

        public override RouteModifier OnNext()
        {
            var selectedFlavoring = AvailableFlavorings.OptionModels.SingleOrDefault( option => option.IsSelected );
            if ( ( selectedFlavoring != null ) && ( selectedFlavoring.GetValue() == Flavorings.JumpToPriorStep ) )
            {
                return new RouteModifier { JumpToPriorStepViewType = typeof(CoffeeTypeSizePageView) };
            }
            else
            {
                return null;
            }
        }

        public override string DisplayName
        {
            get { return "Extras"; }
        }

        public override bool IsValid()
        {
            return true;
        }

    }

}
